package com.zw.gulimall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zw.common.constant.ProductConstant;
import com.zw.common.entity.product.*;
import com.zw.gulimall.product.dao.AttrAttrgroupRelationDao;
import com.zw.gulimall.product.dao.AttrGroupDao;
import com.zw.gulimall.product.dao.CategoryDao;
import com.zw.gulimall.product.service.CategoryService;
import com.zw.gulimall.product.service.ProductAttrValueService;
import com.zw.gulimall.product.vo.AttrResVo;
import com.zw.gulimall.product.vo.AttrVo;
import com.zw.gulimall.product.vo.ProductAttrValueUpdateVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zw.common.utils.PageUtils;
import com.zw.common.utils.Query;

import com.zw.gulimall.product.dao.AttrDao;
import com.zw.gulimall.product.service.AttrService;
import org.springframework.util.CollectionUtils;


@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    @Autowired
    private AttrAttrgroupRelationDao attrAttrgroupRelationDao;

    @Autowired
    private AttrGroupDao attrGroupDao;

    @Autowired
    private CategoryDao categoryDao;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private ProductAttrValueService productAttrValueService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<AttrEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryBaseAttrPage(Map<String, Object> params, Long catelogId, String attrType) {
        Integer attrTypeValue = ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode();
        ;
        if (!"base".equals(attrType)) {
            attrTypeValue = ProductConstant.AttrEnum.ATTR_TYPE_SALE.getCode();
        }

        LambdaQueryWrapper<AttrEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AttrEntity::getAttrType, attrTypeValue);
        if (catelogId != 0) {
            wrapper.eq(AttrEntity::getCatelogId, catelogId);
        }
        String key = (String) params.get("key");
        if (StringUtils.isNotEmpty(key)) {
            wrapper.and(wra -> {
                wra.like(AttrEntity::getAttrId, key)
                        .or().like(AttrEntity::getAttrName, key);
            });
        }
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                wrapper
        );
        List<AttrEntity> entityLists = page.getRecords();
//        组装categoryName和groupName
//        TODO:优化不能在循环中请求接口
//        long start = System.currentTimeMillis();
//        List<AttrResVo> list = entityLists.stream().map(attrEntity -> {
//            AttrResVo attrResVo = new AttrResVo();
//            BeanUtils.copyProperties(attrEntity, attrResVo);
//            AttrAttrgroupRelationEntity attrAttrgroupRelation = attrAttrgroupRelationDao.selectOne(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>()
//                    .eq(AttrAttrgroupRelationEntity::getAttrId, attrEntity.getAttrId()));
//            if (Objects.nonNull(attrAttrgroupRelation)) {
//                AttrGroupEntity groupEntity = attrGroupDao.selectById(attrAttrgroupRelation.getAttrGroupId());
//                attrResVo.setGroupName(groupEntity.getAttrGroupName());
//            }
//            CategoryEntity categoryEntity = categoryDao.selectById(attrEntity.getCatelogId());
//            attrResVo.setCatelogName(categoryEntity.getName());
//            return attrResVo;
//        }).collect(Collectors.toList());
        PageUtils pageUtils = new PageUtils(page);
//        pageUtils.setList(list);
//        long end = System.currentTimeMillis();
//        System.out.printf("消耗时间："+ (end-start));
//        优化
        List<Long> cateGoryIds = entityLists.stream().map(AttrEntity::getCatelogId).collect(Collectors.toList());
        List<Long> attrIds = entityLists.stream().map(AttrEntity::getAttrId).collect(Collectors.toList());

        if(CollectionUtils.isEmpty(cateGoryIds)){
            return pageUtils;
        }
        LambdaQueryWrapper<CategoryEntity> categoryWrapper = new LambdaQueryWrapper<CategoryEntity>()
                .in(CategoryEntity::getCatId, cateGoryIds);
        List<CategoryEntity> categoryEntities = categoryDao.selectList(categoryWrapper);
        List<AttrAttrgroupRelationEntity> relationEntities = attrAttrgroupRelationDao.selectList(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>()
                .in(AttrAttrgroupRelationEntity::getAttrId, attrIds));
        List<Long> attrGroupIds = relationEntities.stream().map(AttrAttrgroupRelationEntity::getAttrGroupId).collect(Collectors.toList());
        List<AttrGroupEntity> attrGroupEntities;
        if (attrGroupIds.size() > 0) {
            attrGroupEntities = attrGroupDao.selectList(new LambdaQueryWrapper<AttrGroupEntity>()
                    .in(AttrGroupEntity::getAttrGroupId, attrGroupIds));
        } else {
            attrGroupEntities = new ArrayList<>();
        }
        List<AttrResVo> list1 = entityLists.stream().map(attrEntity -> {
            AttrResVo attrResVo = new AttrResVo();
            BeanUtils.copyProperties(attrEntity, attrResVo);
            for (CategoryEntity categoryEntity : categoryEntities) {
                if (attrEntity.getCatelogId().equals(categoryEntity.getCatId())) {
                    attrResVo.setCatelogName(categoryEntity.getName());
                }
            }
//            relationEntity.getAttrGroupId().equals(attrGroupEntity.getAttrGroupId()
//                            && attrEntity.getAttrId().equals(relationEntity.getAttrId()))
            if (Objects.equals(attrEntity.getAttrType(), ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode())
                    && Objects.nonNull(attrGroupEntities)) {
                for (AttrGroupEntity attrGroupEntity : attrGroupEntities) {
                    for (AttrAttrgroupRelationEntity relationEntity : relationEntities) {
                        if (Objects.equals(relationEntity.getAttrGroupId(), attrGroupEntity.getAttrGroupId())
                                && Objects.equals(attrEntity.getAttrId(), relationEntity.getAttrId())) {
                            attrResVo.setGroupName(attrGroupEntity.getAttrGroupName());
                        }
                    }
                }
            }
            return attrResVo;
        }).collect(Collectors.toList());
//        Long end2 =  System.currentTimeMillis();
//        System.out.printf("消耗时间："+ (end2-end));
        pageUtils.setList(list1);
        return pageUtils;
    }

    @Override
    public void saveAttr(AttrVo attrVo) {
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attrVo, attrEntity);
        this.save(attrEntity);
        //维护关联表
        if (attrVo.getAttrGroupId() != null
                && Objects.equals(attrVo.getAttrType(), ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode())) {
            AttrAttrgroupRelationEntity relation = new AttrAttrgroupRelationEntity();
            relation.setAttrId(attrEntity.getAttrId());
            relation.setAttrGroupId(attrVo.getAttrGroupId().longValue());
            attrAttrgroupRelationDao.insert(relation);
        }
    }

    @Override
    public AttrResVo getDetailInfo(Long attrId) {
        AttrEntity attrEntity = baseMapper.selectById(attrId);
        AttrResVo attrResVo = new AttrResVo();
        BeanUtils.copyProperties(attrEntity, attrResVo);
        if(Objects.equals(attrEntity.getAttrType(),ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode())){
            AttrAttrgroupRelationEntity relation = attrAttrgroupRelationDao.selectOne(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>()
                    .eq(AttrAttrgroupRelationEntity::getAttrId, attrId));
            if (Objects.nonNull(relation)) {
                attrResVo.setAttrGroupId(relation.getAttrGroupId().intValue());
                attrResVo.setCatelogPath(categoryService.findCatlogPath(attrEntity.getCatelogId()));
            }
        }
        return attrResVo;
    }

    @Override
    public void updateAttr(AttrVo attrVo) {
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attrVo, attrEntity);
        this.saveOrUpdate(attrEntity);
//        维护关联信息
        if (Objects.equals(attrVo.getAttrType(), ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode())) {
            Integer count = attrAttrgroupRelationDao.selectCount(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>()
                    .eq(AttrAttrgroupRelationEntity::getAttrId, attrVo.getAttrId()));
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            relationEntity.setAttrId(attrVo.getAttrId());
            relationEntity.setAttrGroupId(attrVo.getAttrGroupId().longValue());
            if (count > 0) {
                attrAttrgroupRelationDao.updateById(relationEntity);
            } else {
                attrAttrgroupRelationDao.insert(relationEntity);
            }
        }
    }

    @Override
    public List<AttrEntity> queryAttrByCategoryLogId(Long catelogId) {
        return this.baseMapper.selectList(new LambdaQueryWrapper<AttrEntity>()
                .eq(AttrEntity::getCatelogId,catelogId));
    }

    @Override
    public List<ProductAttrValueEntity> attrListForSpu(Long spuId) {
        return productAttrValueService.attrListForSpu(spuId);
    }

    @Override
    public void updateProductAttrValue(List<ProductAttrValueUpdateVo> vos, Long spuId) {
        productAttrValueService.updateProductAttrValue(vos, spuId);
    }

    @Override
    public List<Long> selectSearchAttrIds(ArrayList<Long> ids) {
        return baseMapper.selectSearchAttrIds(ids);
    }


}
